/*

* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* |     Smart-Shop开源商城系统/ Java商城-首选电商平台系统 请务必保留此注释头信息
* |     开源地址: https://gitee.com/ningbo-qishan/gruul-mall
* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* |     可正常分享和学习源码,未经授权 不可商用！
* |     商业版中台购买/开源版商业授权 联系技术客服
* |     官网:  https://www.73app.cn/
* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* |     Copyright (c) 2016-2999 宁波启山智软科技有限公司
* |     版权所有 ,侵权必究！
* ------------------------------------------------------------------------

*/
package com.medusa.gruul.common.core.config;

import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.medusa.gruul.common.core.exception.ServiceException;
import com.medusa.gruul.common.core.jackson.EnumBean;
import com.medusa.gruul.common.core.jackson.EnumBeanSerializer;
import com.medusa.gruul.common.core.jackson.JavaTimeModule;
import com.medusa.gruul.common.core.util.SystemCode;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.time.ZoneId;
import java.util.Locale;
import java.util.TimeZone;

/**
 * Description: JacksonConfig
 * @author : alan
 * Date: 2019/7/13 19:20
 * modify by 张治保
 * date 2021-12-01
 */
@Configuration
@ConditionalOnClass(ObjectMapper.class)
@AutoConfigureBefore(JacksonAutoConfiguration.class)
public class Jackson {

	private static ObjectMapper mapper;
	@Bean
	public Jackson2ObjectMapperBuilderCustomizer customizer() {
		return builder -> {
			builder.locale(Locale.CHINA);
			builder.timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
			builder.simpleDateFormat(DatePattern.NORM_DATETIME_PATTERN);
            SimpleModule simpleModule = new SimpleModule();
            simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
            simpleModule.addSerializer(EnumBean.class,new EnumBeanSerializer());
            builder.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
            builder.featuresToEnable(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS);
            builder.modules(simpleModule, new JavaTimeModule());
			mapper = builder.build();
		};
	}

	/**
	 * 序列化
	 */
	public static String writeValueAsString(Object value){
		try {
			return mapper.writeValueAsString(value);
		} catch (JsonProcessingException e) {
			throw new ServiceException(SystemCode.PARAM_BIND_ERROR);
		}
	}

	/**
	 * 反序列化
	 */
	public static  <T> T readValue(String content, Class<T> valueType){
		try {
			return mapper.readValue(content,valueType);
		} catch (IOException exception) {
			throw new ServiceException(SystemCode.PARAM_BIND_ERROR);
		}
	}


	/**
	 * 反序列化 支持泛型
	 */
	public static  <T> T readValue(String content, TypeReference<T> reference){
		try {
			return mapper.readValue(content,reference);
		} catch (IOException exception) {
			throw new ServiceException(SystemCode.PARAM_BIND_ERROR);
		}
	}
}
